#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <unistd.h>

#include "socketFactory.h"
#include "trackerlogger.h"

extern int LOG_LEVEL;


int newSocketTest(){


    //testando familia
    int newSockFd=0;
    int errorCounter=0;

     // nos testes abaixo se retornar um socket (newSockFd >0) eh pq o teste deu pau

    //testando tipo de socket
    newSockFd = newSocket( -15, 80, "www.google.com");

    if (newSockFd !=INVALID_SOCKTYPE){ puts("newSocketTest failed testing INVALID_SOCKTYPE"); close (newSockFd); errorCounter++;}

    //testando porta
    newSockFd = newSocket(SOCK_STREAM, -5, "www.google.com");
    if (newSockFd != PORT_NUMBER_BELOW_ZERO){ puts("newSocketTest failed testing PORT_NUMBER_BELOW_ZERO"); close (newSockFd); errorCounter++;}

    //testando hostname
    newSockFd = newSocket( SOCK_STREAM, 80, NULL);

    if (newSockFd != NULL_HOSTNAME){ puts("newSocketTest failed testing NULL_HOSTNAME"); close (newSockFd); errorCounter++;}

    //commenting out the test of non-existing domain because my dumb ISP redirects to its own servers if the domain name is not found
    //newSockFd = newSocket(SOCK_STREAM, 70, "randomdnsdomainfortest.com");
    //if (newSockFd !=ERROR_RESOLVING_HOSTNAME) {puts("newSocketTest falhou"); close (newSockFd); errorCounter++;}

    newSockFd = newSocket( SOCK_STREAM, 80, "www.google.com");
    if (newSockFd <0) {puts("newSocketTest failed trying to create a correct socket "); close (newSockFd); errorCounter++;}

    else {close(newSockFd);}

    if (errorCounter ==0){
        puts("newSocketTest OK");
    }

    return errorCounter;
}

int newTCPSocketTest(){

    int newSockFd;
    int errorCounter=0;

    //testando tipo de socket
    newSockFd = newTCPSocket(NULL,  80);

    if (newSockFd !=NULL_HOSTNAME){ puts("newTCPSocketTest falhou"); close (newSockFd);}

    newSockFd = newTCPSocket("www.google.com",  -5);

    if (newSockFd !=PORT_NUMBER_BELOW_ZERO){ puts("newTCPSocketTest falhou"); close (newSockFd);}

    newSockFd = newTCPSocket("www.google.com", 80);

    if (newSockFd <=0){
        puts("newTCPSocketTest falhou");
    }
    else { puts ("newTCPSocketTest OK"); }

    close(newSockFd);
    return errorCounter;
}

int newUDPSocketTest(){

    int newSockFd;
    int errorCounter=0;

    //testando tipo de socket
    newSockFd = newUDPSocket(NULL,  80);

    if (newSockFd !=NULL_HOSTNAME){ puts("newUDPSocketTest falhou"); close (newSockFd); errorCounter++;}

    newSockFd = newUDPSocket("www.google.com",  -5);

    if (newSockFd !=PORT_NUMBER_BELOW_ZERO){ puts("newUDPSocketTest falhou"); close (newSockFd); errorCounter++;}

    newSockFd = newUDPSocket("www.google.com", 80);

    if (newSockFd <=0){
        puts("newUDPSocketTest falhou") ; errorCounter++;
    }

    if (errorCounter ==0) { puts ("newUDPSocketTest OK");}
    else { puts ("newUDPSocketTest falhou");}

    close(newSockFd);

    return errorCounter;
}

int newServerSocketTest(){

    int newSockFd;
    int errorCounter=0;

    newSockFd = newServerSocket(-1, 2000);
    if (newSockFd != INVALID_SOCKTYPE){
       puts("newServerSocketTest falhou testing INVALID_SOCKTYPE"); close(newSockFd); errorCounter++;
    }

    newSockFd = newServerSocket( SOCK_STREAM, -1);
    if (newSockFd != PORT_NUMBER_BELOW_ZERO){
       puts("newServerSocketTest falhou testing PORT_NUMBER_BELOW_ZERO"); close(newSockFd); errorCounter++;
    }

    newSockFd = newServerSocket( SOCK_STREAM, 2000);
    if (newSockFd <0) {puts("newServerSocketTest falhou a correct set up socket"); close (newSockFd); errorCounter++;}


    if (errorCounter ==0){
        puts("newServerSocketTest OK");
    }

    return errorCounter;

}


int newTCPServerSocketTest(){

    int newSockFd;
    int errorCounter=0;

    newSockFd = newTCPServerSocket(-1);
    if (newSockFd != PORT_NUMBER_BELOW_ZERO){
       puts("newTCPServerSocketTest falhou testing PORT_NUMBER_BELOW_ZERO"); close(newSockFd); errorCounter++;
    }

    if (errorCounter ==0){
            puts("newTCPServerSocketTest OK");
        }

    return errorCounter;
}

int newUDPServerSocketTest(){

    int newSockFd;
    int errorCounter=0;

    newSockFd = newUDPServerSocket(-1);
    if (newSockFd != PORT_NUMBER_BELOW_ZERO){
       puts("newUDPServerSocketTest falhou testing PORT_NUMBER_BELOW_ZERO"); close(newSockFd); errorCounter++;
    }

    if (errorCounter ==0){
            puts("newUDPServerSocketTest OK");
        }

    return errorCounter;
}

int unblockSocketTest(){

    int sock = newSocket(SOCK_STREAM, 2500, "www.google.com");

    return 0;
}



int runSocketFactoryTests(){

    LOG_LEVEL=CRITICAL;

    puts ("Starting Socket Factory test suite");
    newSocketTest();
    newTCPSocketTest();
    newUDPSocketTest();
    newServerSocketTest();
    newTCPServerSocketTest();
    newUDPServerSocketTest();
    printf ("Finishing Socket Factory test suite\n");

    return 0;
};


